import { configByID, gameConfig, gameConfigHandle } from "js/config/gameConfig"
import Random from "js/core/random"
import { PlayerModel, TownInfoModel } from "js/model/playerModel"
import { AlchemyType, BagType, ItemType, TownBuildType, TownEffects } from "js/typeDefine/typeDefine"
import equipmentHandle from "./equipmentHandle"
import bagHandle from "./bagHandle"
import { ItemModel } from "js/model/itemModel"
import utils from "js/core/utils"
import playerHandle from "./playerHandle"

class AdventureHandle {

    //根据地图进度算出金币,经验获得值
    getGoldAndExpAmount(player: PlayerModel, time, settlementFlag?: boolean) {
        let mapConfig = gameConfigHandle.configByID[player.adventureInfo.mapID]
        let floor = player.adventureInfo.floor
        let floorLvl = mapConfig.mapLvl + floor - 1
        let amountGold = utils.getIncValue2(gameConfigHandle.gameConfig.map.getGold, floorLvl)
        let amountExp = utils.getIncValue2(gameConfigHandle.gameConfig.map.getExp, floorLvl)
        // 营地加成
        let campLvl = player.teamList.campLvl
        let campExp = utils.getIncValue(gameConfig.partner.campExp, campLvl)
        amountExp += campExp

        // 炼金加成
        let alchemyConfig: any = Object.entries(gameConfig.alchemy).find(a => {
            let config: any = a[1]
            return config.aType == AlchemyType.Gold
        })
        let lvl = player.alchemyInfo.lvls[alchemyConfig[0]] || 0
        let addPer = lvl ? utils.getIncValue(alchemyConfig[1].values, lvl) : 0
        amountGold = Math.floor((1 + addPer / 100) * amountGold)

        alchemyConfig = Object.entries(gameConfig.alchemy).find(a => {
            let config: any = a[1]
            return config.aType == AlchemyType.Exp
        })
        lvl = player.alchemyInfo.lvls[alchemyConfig[0]] || 0
        addPer = lvl ? utils.getIncValue(alchemyConfig[1].values, lvl) : 0
        amountExp = Math.floor((1 + addPer / 100) * amountExp)

        // 城镇加成
        if (!player.townInfo) {
            player.townInfo = new TownInfoModel({})
        }
        let townLvl = player.townInfo.lvl
        let townConfig = gameConfig.town.list.find(l => l.kind == TownBuildType.Town)
        let addGoldPer = 100, addExpPer = 100;
        Object.entries(townConfig.effects[TownEffects.AddPerOfResources] || {}).forEach(effect => {
            let name = effect[0]
            let v: any = effect[1]
            let value = utils.getIncValue(v.values, townLvl)
            if (name == 'gold' && townLvl >= v.limitLvl) {
                addGoldPer += value
            } else if (name == 'exp' && townLvl >= v.limitLvl) {
                addExpPer += value
            }
        });
        amountGold = Math.floor(amountGold * addGoldPer / 100)
        amountExp = Math.floor(amountExp * addExpPer / 100)

        //称号
        let titles = player.titleInfo?.infos || {}
        let addPer1 = []
        Object.entries(titles).forEach(t => {
            let id = t[0]
            let config = gameConfigHandle.configByID[id]
            if (config) {
                Object.entries(config.effect).forEach(e => {
                    let name = e[0]
                    if (name == 'resources') {
                        addPer1.push(e[1])
                    }
                })
            }
        })
        addGoldPer = 100, addExpPer = 100
        addPer1.forEach(ap => {
            Object.entries(ap).forEach(a => {
                let name = a[0]
                let value: any = a[1]
                if (name == 'gold') {
                    addGoldPer += value
                } else if (name == 'exp') {
                    addExpPer += value
                }
            })
        })
        amountGold = Math.floor(amountGold * addGoldPer / 100)
        amountExp = Math.floor(amountExp * addExpPer / 100)

        if (playerHandle.isMember(player, time)) {
            amountGold = Math.floor((1 + gameConfig.vip.getPerOfAfd / 100) * amountGold)
            amountExp = Math.floor((1 + gameConfig.vip.getPerOfAfd / 100) * amountExp)
        }
        if (player.baseInfo.longVip) {
            amountGold = Math.floor((1 + gameConfig.vip.getPerOfLongVip / 100) * amountGold)
            amountExp = Math.floor((1 + gameConfig.vip.getPerOfLongVip / 100) * amountExp)
        }
        let vip = playerHandle.getVipLvl(player)
        if (vip) {
            amountGold += Math.floor(amountGold * gameConfig.vip.addGoldper[vip] / 100)
            amountExp += Math.floor(amountExp * gameConfig.vip.addExpPer[vip] / 100)
        }
        let amountDiamond2 = 0
        let gameMode = player.gameSet.gameMode
        if (settlementFlag) {
            amountDiamond2 = utils.getIncValue(gameConfig.map.getDiamond2, 1)
        }
        else if (gameMode && player.adventureInfo.hangupInfo && player.adventureInfo.hangupInfo.hangup && player.adventureInfo.hangupInfo.mapID) {
            let mapComfig = gameConfigHandle.configByID[player.adventureInfo.hangupInfo.mapID]
            let mapLvl = mapComfig.mapLvl || 100
            amountDiamond2 = utils.getIncValue(gameConfig.map.getDiamond2, Math.floor((mapLvl - 100) / 10))
        }
        return [amountGold, amountExp, amountDiamond2]
    }

    //自动判断物品类型 添加到对应的背包中 装备将随机生成品级,五行等
    async addItemAuto(player: PlayerModel, itemId: number, num: number, rand: Random, lvl?: number, creatKind?: number) {
        let it = gameConfigHandle.configByID[itemId]
        lvl = lvl || 1
        if (it.kind == ItemType.Prop) {
            bagHandle.AddItem(player.bag, itemId, num, rand)
        } else if (it.kind == ItemType.Equipment) {
            let mapID = player.adventureInfo.mapID
            let lvl = configByID[mapID].mapLvl
            let equipmentItem = equipmentHandle.create(player, itemId, lvl, rand, creatKind)
            bagHandle.AddItemComponent(player.equipmentBag, equipmentItem)
        }
    }

    //根据所选方案出售装备背包里的装备
    sellEquipment(planId: number, player: PlayerModel) {
        let money = 0
        let gold = 0
        let sellAmount = 0
        let equipments = player.equipmentBag.items
        let bag = player.equipmentBag
        let getItems = {}
        equipments.forEach(element => {
            if (element) {
                let getData = equipmentHandle.getPriceOfEquipment(element)

                if (!getItems[getData.itemID]) {
                    getItems[getData.itemID] = 0
                }
                getItems[getData.itemID] += getData.amount
                bagHandle.removeItemByPosition(player.equipmentBag, element.pos)

            }
        })
        let getFromSell = { getItems, sellAmount }
        return getFromSell
    }

    getAdventureResource(player: PlayerModel, time: number, random: Random) {
        //爵位增加的收益
        let getResourceInterval = gameConfigHandle.gameConfig.base.getResourceInterval
        let getTimes = Math.floor((time - player.getResourceDate) / getResourceInterval)
        if (getTimes > 24 * 60 * 2) {
            getTimes = 24 * 60 * 2
        }
        if (getTimes > 0) {
            let mapID = player.adventureInfo.mapID
            let mapConfig = configByID[mapID]
            let floorLvl = mapConfig.mapLvl + player.adventureInfo.floor - 1
            if (mapConfig.endless) {
                floorLvl = mapConfig.mapLvl
            }
            let goldExpAmount = adventureHandle.getGoldAndExpAmount(player, time)
            // 材料掉落
            let getItems = {}
            let goldAmount = 0, diamond2Amount = 0
            // 新大陆挂机
            let newLandHangup = player.adventureInfo.hangupInfo
                && player.adventureInfo.hangupInfo.hangup
                && player.adventureInfo.hangupInfo.mapID
            if (newLandHangup) {
                let newMapID = player.adventureInfo.hangupInfo.mapID
                let newMapConfig = gameConfigHandle.configByID[newMapID]
                let mapLvl = Math.floor(((newMapConfig.mapLvl || 100) - 100) / 10)
                diamond2Amount = Math.floor(utils.getIncValue(gameConfig.map.getDiamond2, mapLvl) * getTimes / 2)
                // 异界材料
                let maxGetTime = getTimes > 24 * 60 ? 24 * 60 : getTimes
                let dropItems = newMapConfig.dropItems
                let dropAmount = 0, rareAmount = 0
                for (let i = 0; i < maxGetTime; i++) {
                    let itemRandom = new Random(i * random.getSeed())
                    if (itemRandom.intn(100) < (newMapConfig.dropRate || gameConfig.newland.dropRate)) {
                        let amount = utils.getIncValue(gameConfigHandle.gameConfig.newland.getResource, mapLvl)
                        dropAmount += amount
                    }
                    if (itemRandom.intn(10000) < (newMapConfig.rareDropRate * 100 || gameConfig.newland.rareDropRate * 100)) {
                        let amount = utils.getIncValue(gameConfigHandle.gameConfig.newland.getResource, mapLvl)
                        rareAmount += amount
                    }
                }
                for (let j = 0; j < dropItems.length && dropAmount; j++) {
                    getItems[dropItems[j]] = dropAmount
                    adventureHandle.addItemAuto(player, dropItems[j], dropAmount, random)
                }
                let rareDropItems = newMapConfig.rareDropItems
                for (let j = 0; j < rareDropItems.length && rareAmount; j++) {
                    getItems[rareDropItems[j]] = rareAmount
                    adventureHandle.addItemAuto(player, rareDropItems[j], rareAmount, random)
                }
            } else {
                goldAmount = Math.floor(goldExpAmount[0] * getTimes)

                //获得材料
                let dropItems = gameConfigHandle.gameConfig.map.mapDropItemList.slice(0)
                let amount = utils.getIncValue(gameConfigHandle.gameConfig.map.getResource, floorLvl)
                    * getTimes
                amount = Math.floor(amount)
                for (let i = 0; i < dropItems.length; i++) {
                    getItems[dropItems[i]] = amount
                    adventureHandle.addItemAuto(player, dropItems[i], amount, random)
                }
            }
            let expAmount = Math.floor(goldExpAmount[1] * getTimes)
            if (newLandHangup) {
                player.itemInfo.diamond2 += diamond2Amount
            } else {
                player.itemInfo.gold += goldAmount
            }
            player.teamList.list.forEach(p => {
                if (p) {
                    p.exp += expAmount
                }
            })

            //营地经验
            let campLvl = player.teamList.campLvl
            let campExp = utils.getIncValue(gameConfig.partner.campExp, campLvl)
            player.teamList.camp.forEach(p => {
                if (p) {
                    p.exp += campExp
                }
            })

            //获得装备
            let getEquipmentAmount = [0, 0, 0, 0, 0, 0]
            let distroyEquipment = [0, 0, 0, 0, 0, 0]
            let dropRate = gameConfigHandle.gameConfig.map.dropRate
            let getEquipments: ItemModel[] = []
            let getEquipCheck = newLandHangup || !player.gameSet.gameMode
            let dropRateNum
            if (newLandHangup) {
                dropRateNum = utils.getIncValue(gameConfig.map.fantasyDropRate, 0)
            } else[
                dropRateNum = utils.getIncValue(dropRate, 0)
            ]
            for (let j = 0; j < getTimes && getEquipCheck; j++) {
                let sjs = random.intn(100)
                if (sjs < dropRateNum) {
                    let equipment
                    if (newLandHangup) {
                        let newMapID = player.adventureInfo.hangupInfo.mapID
                        let newMapConfig = gameConfigHandle.configByID[newMapID]
                        let newMapLvl = newMapConfig.mapLvl || 100
                        equipment = equipmentHandle.createForFantasy(player, null, newMapLvl, random, null)
                    } else {
                        equipment = equipmentHandle.create(player, null, floorLvl, random, null)
                    }
                    getEquipments.push(equipment)
                    getEquipmentAmount[equipment.equipment.quality - 1]++
                    if (player.adventureInfo.autoSellSet[BagType.Equipment] && player.adventureInfo.autoSellSet[BagType.Equipment][equipment.equipment.quality - 1]) {
                        let getData: any = equipmentHandle.getPriceOfEquipment(equipment)
                        if (!getItems[getData.itemID]) {
                            getItems[getData.itemID] = 0
                        }
                        getItems[getData.itemID] += getData.amount
                        bagHandle.AddItem(player.bag, getData.itemID, getData.amount, random)
                        distroyEquipment[equipment.equipment.quality - 1]++
                    } else if (player.adventureInfo.autoSellSet[BagType.Equipment2] && player.adventureInfo.autoSellSet[BagType.Equipment2][equipment.equipment.quality - 1]) {
                        let getData: any = equipmentHandle.getPriceOfEquipment(equipment)
                        if (!getItems[getData.itemID]) {
                            getItems[getData.itemID] = 0
                        }
                        getItems[getData.itemID] += getData.amount
                        bagHandle.AddItem(player.bag, getData.itemID, getData.amount, random)
                        distroyEquipment[equipment.equipment.quality - 1]++
                    } else {
                        let bag
                        if (newLandHangup) {
                            bag = player.equipmentBag2
                        } else {
                            bag = player.equipmentBag
                        }
                        let res = bagHandle.AddItemComponent(bag, equipment)
                        if (!res) {
                            let getData: any = equipmentHandle.getPriceOfEquipment(equipment)
                            if (!getItems[getData.itemID]) {
                                getItems[getData.itemID] = 0
                            }
                            getItems[getData.itemID] += getData.amount
                            bagHandle.AddItem(player.bag, getData.itemID, getData.amount, random)
                            distroyEquipment[equipment.equipment.quality - 1]++
                        }
                    }
                }
            }
            player.getResourceDate += getTimes * getResourceInterval
            player.baseInfo.times += getTimes
            let leaveMin = getResourceInterval * getTimes / 60000
            let upPerOfExp = 0, upPerOfGold = 0
            if (getTimes >= gameConfigHandle.gameConfig.map.leaveGet) {
                let msg = {
                    upPerOfGold, upPerOfExp,
                    leaveMin, getTimes, goldAmount, expAmount, getItems, getEquipmentAmount,
                    distroyEquipment: distroyEquipment,
                    diamond2Amount,
                }
                return { resourceGetTimes: getTimes, resourceData: msg }
            }
        }
        return { resourceGetTimes: getTimes }
    }
}
let adventureHandle = new AdventureHandle()
export default adventureHandle